package services

import (
	"encoding/json"
	"net/http"
	"regexp"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/diogoxiang/smock/database"
	"github.com/diogoxiang/smock/models"
)

// HandleMockRequest 处理模拟请求
func HandleMockRequest(c *gin.Context) {
	path := c.Request.URL.Path
	method := c.Request.Method
	
	// 查找匹配的API
	var mockAPIs []models.MockAPI
	database.DB.Where("method = ?", method).Find(&mockAPIs)
	
	var matchedAPI *models.MockAPI
	for _, api := range mockAPIs {
		// 检查路径是否匹配
		if pathMatches(api.Path, path) {
			matchedAPI = &api
			break
		}
	}
	
	if matchedAPI == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "No matching mock API found"})
		return
	}
	
	// 加载响应和规则
	database.DB.Preload("Responses").Preload("Rules").First(matchedAPI, matchedAPI.ID)
	
	// 查找匹配的响应
	response := findMatchingResponse(c, matchedAPI)
	
	// 记录请求
	logRequest(c, matchedAPI, response)
	
	// 设置响应头
	var headers map[string]string
	if response.Headers != "" {
		json.Unmarshal([]byte(response.Headers), &headers)
		for key, value := range headers {
			c.Header(key, value)
		}
	}
	
	// 设置内容类型
	c.Header("Content-Type", response.ContentType)
	
	// 如果有延迟，等待指定时间
	if response.Delay > 0 {
		time.Sleep(time.Duration(response.Delay) * time.Millisecond)
	}
	
	// 返回响应
	c.String(response.StatusCode, response.Body)
}

// pathMatches 检查请求路径是否匹配API路径
func pathMatches(apiPath, requestPath string) bool {
	// 支持简单的路径参数，如 /api/:id
	apiParts := strings.Split(apiPath, "/")
	requestParts := strings.Split(requestPath, "/")
	
	if len(apiParts) != len(requestParts) {
		return false
	}
	
	for i, part := range apiParts {
		if strings.HasPrefix(part, ":") {
			// 这是一个参数，跳过检查
			continue
		}
		if part != requestParts[i] {
			return false
		}
	}
	
	return true
}

// findMatchingResponse 查找匹配的响应
func findMatchingResponse(c *gin.Context, api *models.MockAPI) models.MockResponse {
	// 默认响应
	var defaultResponse models.MockResponse
	for _, resp := range api.Responses {
		if resp.IsDefault {
			defaultResponse = resp
			break
		}
	}
	
	// 如果没有规则，直接返回默认响应
	if len(api.Rules) == 0 {
		return defaultResponse
	}
	
	// 检查每个响应的规则是否匹配
	for _, rule := range api.Rules {
		if ruleMatches(c, rule) {
			// 找到匹配规则对应的响应
			for _, resp := range api.Responses {
				if resp.ID == rule.ID {
					return resp
				}
			}
		}
	}
	
	// 没有匹配的规则，返回默认响应
	return defaultResponse
}

// ruleMatches 检查请求是否匹配规则
func ruleMatches(c *gin.Context, rule models.MatchRule) bool {
	var value string
	
	switch rule.Type {
	case "path":
		value = c.Param(rule.Key)
	case "query":
		value = c.Query(rule.Key)
	case "header":
		value = c.GetHeader(rule.Key)
	case "body":
		// 简单处理，实际可能需要更复杂的JSON解析
		var body map[string]interface{}
		c.ShouldBindJSON(&body)
		if val, ok := body[rule.Key]; ok {
			value = val.(string)
		}
	}
	
	switch rule.Operator {
	case "eq":
		return value == rule.Value
	case "neq":
		return value != rule.Value
	case "contains":
		return strings.Contains(value, rule.Value)
	case "regex":
		match, _ := regexp.MatchString(rule.Value, value)
		return match
	}
	
	return false
}

// logRequest 记录请求
func logRequest(c *gin.Context, api *models.MockAPI, response models.MockResponse) {
	// 读取请求体
	var bodyBytes []byte
	if c.Request.Body != nil {
		bodyBytes, _ = c.GetRawData()
		// 重新设置请求体，因为读取后会消耗
		c.Request.Body = &readCloser{strings.NewReader(string(bodyBytes))}
	}
	
	// 收集请求头
	headers := make(map[string]string)
	for k, v := range c.Request.Header {
		if len(v) > 0 {
			headers[k] = v[0]
		}
	}
	headersJSON, _ := json.Marshal(headers)
	
	// 创建日志记录
	log := models.RequestLog{
		MockAPIID:      api.ID,
		Path:           c.Request.URL.Path,
		Method:         c.Request.Method,
		RequestHeaders: string(headersJSON),
		RequestBody:    string(bodyBytes),
		ResponseID:     response.ID,
		StatusCode:     response.StatusCode,
		ResponseTime:   response.Delay,
		CreatedAt:      time.Now(),
	}
	
	database.DB.Create(&log)
}

// readCloser 实现io.ReadCloser接口
type readCloser struct {
	*strings.Reader
}

func (rc *readCloser) Close() error {
	return nil
}